<template>
  <teleport to="body">
    <div class="z-loading-bar">
      <div :class="[state, color]" class="h-full" />
    </div>
    <slot></slot>
  </teleport>
</template>
<script lang="ts">
import { defineComponent, ref, provide, InjectionKey, inject } from "vue";
export interface LoadingBar {
  start: () => void;
  end: () => void;
  error: () => void;
}
export const loadingBarInjectKey: InjectionKey<LoadingBar> =
  Symbol("loading-bar");

export const useLoadingBar = () => inject(loadingBarInjectKey);

export default defineComponent({
  name: "ZLoadingBar",
  setup() {
    const state = ref("hidden"),
      color = ref("bg-emerald-400");

    const start = () => {
        state.value = "start-loading";
        color.value = "bg-emerald-400";
      },
      end = () => {
        state.value = "end-loading";
        setTimeout(() => {
          state.value = "hidden";
        }, 500);
      },
      error = () => {
        color.value = "bg-rose-400";
        state.value = "error-loading";
        setTimeout(() => {
          state.value = "hidden";
        }, 500);
      };
    provide(loadingBarInjectKey, { start, end, error });
    return {
      state,
      color,
    };
  },
});
</script>
<style>
.z-loading-bar {
  z-index: 5999;
  position: absolute;
  top: 0px;
  right: 0px;
  left: 0px;
  height: 2px;
}
.start-loading {
  animation: loading-start 1.5s linear;
}
.end-loading {
  animation: loading-end 0.5s linear;
}
.error-loading {
  animation: loading-error 0.5s linear;
}
@keyframes loading-start {
  0% {
    width: 0%;
  }
  100% {
    width: 80%;
  }
}
@keyframes loading-end {
  0% {
    width: 80%;
  }
  100% {
    width: 100%;
  }
}
@keyframes loading-error {
  0% {
    width: 0;
  }
  100% {
    width: 100%;
  }
}
</style>
